package com.bmth.alise.client;

import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;

import com.bmth.alise.client.config.Configuration;

public class UrlRegexMapping {

	private static String includeRegex;
	private static String excludeRegex;
	private static Map<String, String> includeRegexMapping = new HashMap<>();
	private static Map<String, String> excludeRegexMapping = new HashMap<>();

	private static Pattern p = Pattern.compile("[\\w\\d\\.]+\\.([\\w\\d]+\\.[\\w\\d])");

	public static void init() {
		try {
			UrlRegexMapping.includeRegex = Configuration.getProperty("AcceptRegex");
			UrlRegexMapping.excludeRegex = Configuration.getProperty("ExcludeRegex");
			InputStream ins = Thread.currentThread().getContextClassLoader().getResourceAsStream("url_regex.txt");
			@SuppressWarnings("unchecked")
			List<String> lines = IOUtils.readLines(ins);
			for (String line : lines) {
				String[] line_ = line.split(";");
				if (line_.length == 3 && !line.startsWith("#")) {
					String host = line_[0];
					String include = line_[1];
					String exclude = line_[2];
					includeRegexMapping.put(host, include);
					excludeRegexMapping.put(host, exclude);
				}
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	public static boolean filter(String url) {
		String firstLevelHost = getFirstLevelHost(url);
		String includeRegex = includeRegexMapping.get(firstLevelHost);
		String excludeRegex = excludeRegexMapping.get(firstLevelHost);

		boolean includeMatches = false;
		if (StringUtils.isNotBlank(includeRegex)) {
			includeMatches = url.matches(includeRegex);
		} else {
			includeMatches = url.matches(UrlRegexMapping.includeRegex);
		}
		if (!includeMatches) {
			return false;
		}
		boolean excludeMatches = true;
		if (StringUtils.isNotBlank(excludeRegex)) {
			excludeMatches = !url.matches(excludeRegex);
		} else if (StringUtils.isNotBlank(UrlRegexMapping.excludeRegex)) {
			excludeMatches = !url.matches(UrlRegexMapping.excludeRegex);
		}
		return includeMatches && !excludeMatches;
	}

	public static String getIncludeRegex(String url) {
		String firstLevelHost = getFirstLevelHost(url);
		String regex = includeRegexMapping.get(firstLevelHost);
		return StringUtils.isNotBlank(regex) ? regex : UrlRegexMapping.includeRegex;
	}

	public static String getFirstLevelHost(String url) {
		String firstLevelHost = null;
		try {
			URL u = new URL(url);
			String host = u.getHost();
			Matcher m = p.matcher(host);
			while (m.find()) {
				firstLevelHost = m.group(1);
			}
		} catch (Exception e) {
			e.printStackTrace();
		}
		return firstLevelHost;
	}
}
